<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>中俊为 | we harmonyos</title>
    <meta name="generator" content="VuePress 1.9.7">
    <script>
          var _hmt = _hmt || [];
          (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?39485dba914ae63b24732b6a90688f0b";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
          })();
      </script>
    <link rel="manifest" href="/manifest.webmanifest" crossorigin="use-credentials">
    <meta name="description" content="weharmonyos 鸿蒙论坛 鸿蒙注释 开源鸿蒙 鸿蒙源码 openharmony源码 HarmonyOS源码 HarmonyOS HarmonyOS生态 openharmony开发者文档 鸿蒙生态 鸿蒙系统 华为操作系统 鸿蒙研究站 开放原子开源基金会 百万汉字注解鸿蒙 百篇博客分析鸿蒙">
    <meta property="og:url" content="/blog/50.html">
    <meta property="og:site_name" content="中俊为 | we harmonyos">
    <meta property="og:description" content="本篇关键词：、、、 下载 &gt;&gt; 离线文档.鸿蒙内核源码分析(百篇博客分析.挖透鸿蒙内核).pdf.zip) 通讯机制相关篇为: v41.04 鸿蒙内核源码分析(通讯总览) | 内核跟人一样都喜欢八卦; v42.08 鸿蒙内核源码分析(自旋锁) | 死等丈夫归来的贞洁烈女; v43.05 鸿蒙内核源码分析(互斥锁) | 有你没她 相安无事; v44.0">
    <meta property="og:type" content="article">
    <meta property="og:locale" content="en-US">
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:image:alt" content="中俊为 | we harmonyos">
    <meta name="theme-color" content="#46bd87">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
    
    <link rel="preload" href="/assets/css/0.styles.087eb7d3.css" as="style"><link rel="preload" href="/assets/js/app.9a8b95d8.js" as="script"><link rel="preload" href="/assets/js/vendors~layout-Layout.c1e797d4.js" as="script"><link rel="preload" href="/assets/js/vendors~layout-Blog~layout-Layout~layout-NotFound.f75cf258.js" as="script"><link rel="preload" href="/assets/js/page--48302d68.8d6493cf.js" as="script"><link rel="prefetch" href="/assets/js/160.a8046d43.js"><link rel="prefetch" href="/assets/js/161.29f8564f.js"><link rel="prefetch" href="/assets/js/162.249ee491.js"><link rel="prefetch" href="/assets/js/163.c57d1577.js"><link rel="prefetch" href="/assets/js/164.7a788aaa.js"><link rel="prefetch" href="/assets/js/165.c333afb2.js"><link rel="prefetch" href="/assets/js/166.9bcb7cd6.js"><link rel="prefetch" href="/assets/js/layout-Blog.4a9781d1.js"><link rel="prefetch" href="/assets/js/layout-Layout.7e277e0b.js"><link rel="prefetch" href="/assets/js/layout-NotFound.9326b14e.js"><link rel="prefetch" href="/assets/js/layout-Slide.8dd861e4.js"><link rel="prefetch" href="/assets/js/page--00854288.e2bc8e8a.js"><link rel="prefetch" href="/assets/js/page--00f8db0a.b2a35fe6.js"><link rel="prefetch" href="/assets/js/page--03ad6df0.d48f4c19.js"><link rel="prefetch" href="/assets/js/page--04b12ba8.e8add78d.js"><link rel="prefetch" href="/assets/js/page--070d2528.d24cd503.js"><link rel="prefetch" href="/assets/js/page--086560f0.a6be2844.js"><link rel="prefetch" href="/assets/js/page--090ad32d.fc7da3c3.js"><link rel="prefetch" href="/assets/js/page--0c054030.2886024e.js"><link rel="prefetch" href="/assets/js/page--0d9507c8.a27dee03.js"><link rel="prefetch" href="/assets/js/page--10bd3330.b5165172.js"><link rel="prefetch" href="/assets/js/page--1233b0b2.b5caca9c.js"><link rel="prefetch" href="/assets/js/page--13650e88.61330a2b.js"><link rel="prefetch" href="/assets/js/page--14c850b1.d9a40c31.js"><link rel="prefetch" href="/assets/js/page--15752630.25f9c756.js"><link rel="prefetch" href="/assets/js/page--19150570.58df8995.js"><link rel="prefetch" href="/assets/js/page--19ecf128.130d012b.js"><link rel="prefetch" href="/assets/js/page--1c48eaa8.9a689e30.js"><link rel="prefetch" href="/assets/js/page--1d4dfe96.bd551921.js"><link rel="prefetch" href="/assets/js/page--1dccf870.03d7d9cc.js"><link rel="prefetch" href="/assets/js/page--2074d3c8.06bf5706.js"><link rel="prefetch" href="/assets/js/page--22213c96.e703257a.js"><link rel="prefetch" href="/assets/js/page--2284eb70.514124de.js"><link rel="prefetch" href="/assets/js/page--22d0cd48.11ea1522.js"><link rel="prefetch" href="/assets/js/page--252cc6c8.f9acae83.js"><link rel="prefetch" href="/assets/js/page--2624cab0.4535fea2.js"><link rel="prefetch" href="/assets/js/page--269ff8f9.012e8ae6.js"><link rel="prefetch" href="/assets/js/page--26fcb668.35b2da5d.js"><link rel="prefetch" href="/assets/js/page--2958afe8.216913bc.js"><link rel="prefetch" href="/assets/js/page--2adcbdb0.6dcb4c27.js"><link rel="prefetch" href="/assets/js/page--2bb4a968.aac31797.js"><link rel="prefetch" href="/assets/js/page--2d849908.7bb4e817.js"><link rel="prefetch" href="/assets/js/page--2e10a2e8.42bef48d.js"><link rel="prefetch" href="/assets/js/page--2f94b0b0.0c993df5.js"><link rel="prefetch" href="/assets/js/page--2fe09288.77769dcb.js"><link rel="prefetch" href="/assets/js/page--323c8c08.254a5f78.js"><link rel="prefetch" href="/assets/js/page--33348ff0.a5f99eb0.js"><link rel="prefetch" href="/assets/js/page--340c7ba8.2c9570cb.js"><link rel="prefetch" href="/assets/js/page--34988588.8c8d0363.js"><link rel="prefetch" href="/assets/js/page--36687528.67d84e0d.js"><link rel="prefetch" href="/assets/js/page--37d6dfd6.88e9cd42.js"><link rel="prefetch" href="/assets/js/page--37ec82f0.5419c82d.js"><link rel="prefetch" href="/assets/js/page--37f7cf15.65f72e55.js"><link rel="prefetch" href="/assets/js/page--38c46ea8.5d5150f9.js"><link rel="prefetch" href="/assets/js/page--3a945e48.bf9758fb.js"><link rel="prefetch" href="/assets/js/page--3ab2204c.e08d6316.js"><link rel="prefetch" href="/assets/js/page--3b206828.d83e3926.js"><link rel="prefetch" href="/assets/js/page--3ca475f0.49e5acce.js"><link rel="prefetch" href="/assets/js/page--3cf057c8.8364331d.js"><link rel="prefetch" href="/assets/js/page--3f4c5148.587a8360.js"><link rel="prefetch" href="/assets/js/page--40445530.486bb516.js"><link rel="prefetch" href="/assets/js/page--411c40e8.2eedba0e.js"><link rel="prefetch" href="/assets/js/page--41a84ac8.f4a360a3.js"><link rel="prefetch" href="/assets/js/page--4220f8b5.19b4371f.js"><link rel="prefetch" href="/assets/js/page--43783a68.4faf0866.js"><link rel="prefetch" href="/assets/js/page--44fc4830.a160662c.js"><link rel="prefetch" href="/assets/js/page--45d433e8.560fef87.js"><link rel="prefetch" href="/assets/js/page--47a42388.052314b4.js"><link rel="prefetch" href="/assets/js/page--47d07816.66731286.js"><link rel="prefetch" href="/assets/js/page--49b43b30.e3684736.js"><link rel="prefetch" href="/assets/js/page--4a001d08.47f7ec45.js"><link rel="prefetch" href="/assets/js/page--4c5c1688.b7ec1f32.js"><link rel="prefetch" href="/assets/js/page--4d541a70.ee807705.js"><link rel="prefetch" href="/assets/js/page--4e2c0628.4f7105a4.js"><link rel="prefetch" href="/assets/js/page--4eb81008.725d26fe.js"><link rel="prefetch" href="/assets/js/page--5087ffa8.dac2aae0.js"><link rel="prefetch" href="/assets/js/page--520c0d70.2beedefb.js"><link rel="prefetch" href="/assets/js/page--52e3f928.2645087c.js"><link rel="prefetch" href="/assets/js/page--53cd0b44.96d4a285.js"><link rel="prefetch" href="/assets/js/page--54eb2c5e.27eb702b.js"><link rel="prefetch" href="/assets/js/page--553ff2a8.fba8ee4f.js"><link rel="prefetch" href="/assets/js/page--5686ab01.547b633c.js"><link rel="prefetch" href="/assets/js/page--56c40070.4e35708a.js"><link rel="prefetch" href="/assets/js/page--570fe248.2b301b36.js"><link rel="prefetch" href="/assets/js/page--596bdbc8.c74cd724.js"><link rel="prefetch" href="/assets/js/page--5a63dfb0.bbd49a9b.js"><link rel="prefetch" href="/assets/js/page--5bc7d548.eda26865.js"><link rel="prefetch" href="/assets/js/page--5f1bd2b0.e02cf88d.js"><link rel="prefetch" href="/assets/js/page--5ff3be68.b2b0e76e.js"><link rel="prefetch" href="/assets/js/page--624fb7e8.666fdc84.js"><link rel="prefetch" href="/assets/js/page--63d3c5b0.b587d38f.js"><link rel="prefetch" href="/assets/js/page--68d79a88.86f62e4d.js"><link rel="prefetch" href="/assets/js/page--6c2b97f0.ed46abea.js"><link rel="prefetch" href="/assets/js/page--6cc6a596.b3827451.js"><link rel="prefetch" href="/assets/js/page--6ea7a148.61a9bc10.js"><link rel="prefetch" href="/assets/js/page--70e38af0.eb8ffc53.js"><link rel="prefetch" href="/assets/js/page--7180d470.73a3a20e.js"><link rel="prefetch" href="/assets/js/page--752f83e8.d5c31640.js"><link rel="prefetch" href="/assets/js/page--778b7d68.5e8e5ea9.js"><link rel="prefetch" href="/assets/js/page--7bb76688.53e305e3.js"><link rel="prefetch" href="/assets/js/page--7c59a86a.ecf88c30.js"><link rel="prefetch" href="/assets/js/page--7df35030.cfa388f4.js"><link rel="prefetch" href="/assets/js/page--7e136008.230e9a15.js"><link rel="prefetch" href="/assets/js/page--89935db0.f79f9e25.js"><link rel="prefetch" href="/assets/js/page--96a322f0.412d537f.js"><link rel="prefetch" href="/assets/js/page--9b5b15f0.a5231547.js"><link rel="prefetch" href="/assets/js/page--a3b2e830.f4ba68fa.js"><link rel="prefetch" href="/assets/js/page--a86adb30.ec08486b.js"><link rel="prefetch" href="/assets/js/page--ad22ce30.4872eca4.js"><link rel="prefetch" href="/assets/js/page--b0c2ad70.8637057e.js"><link rel="prefetch" href="/assets/js/page--b57aa070.43215f9e.js"><link rel="prefetch" href="/assets/js/page--ba329370.b5f22d13.js"><link rel="prefetch" href="/assets/js/page--bdd272b0.aff1d1a9.js"><link rel="prefetch" href="/assets/js/page--c28a65b0.978514c4.js"><link rel="prefetch" href="/assets/js/page--c606edca.49d3396e.js"><link rel="prefetch" href="/assets/js/page--c74258b0.f85195bc.js"><link rel="prefetch" href="/assets/js/page--cae237f0.8a976cc1.js"><link rel="prefetch" href="/assets/js/page--cf9a2af0.7ad20ea2.js"><link rel="prefetch" href="/assets/js/page--d4521df0.a0a74934.js"><link rel="prefetch" href="/assets/js/page--d7f1fd30.160f138a.js"><link rel="prefetch" href="/assets/js/page--dca9f030.9127ab28.js"><link rel="prefetch" href="/assets/js/page--e161e330.34876a6f.js"><link rel="prefetch" href="/assets/js/page--e4f35ef4.690d3ccb.js"><link rel="prefetch" href="/assets/js/page--e501c270.8dc088ee.js"><link rel="prefetch" href="/assets/js/page--e9b9b570.b94764ed.js"><link rel="prefetch" href="/assets/js/page--ea4e0a70.94492571.js"><link rel="prefetch" href="/assets/js/page--ee71a870.b9944792.js"><link rel="prefetch" href="/assets/js/page--f21187b0.d00a5788.js"><link rel="prefetch" href="/assets/js/page--f6c97ab0.ecb91d64.js"><link rel="prefetch" href="/assets/js/page--fb816db0.c1f07c37.js"><link rel="prefetch" href="/assets/js/page--fcf2f51e.71000d71.js"><link rel="prefetch" href="/assets/js/page--ff214cf0.aaa8b0fc.js"><link rel="prefetch" href="/assets/js/page-GN.2f20b55f.js"><link rel="prefetch" href="/assets/js/page-GNFrequentlyAskedQuestions.24e61c26.js"><link rel="prefetch" href="/assets/js/page-GNLanguageandOperation.35e22ff2.js"><link rel="prefetch" href="/assets/js/page-GNQuickStartguide.7cd8e521.js"><link rel="prefetch" href="/assets/js/page-GNReference.1d5d0c6c.js"><link rel="prefetch" href="/assets/js/page-GNSimpleBuildExample.2eb0b7eb.js"><link rel="prefetch" href="/assets/js/page-GNStyleGuide.8a407135.js"><link rel="prefetch" href="/assets/js/page-GNU汇编教程.d208e4d7.js"><link rel="prefetch" href="/assets/js/page-GNvimsyntaxplugin.58d1459e.js"><link rel="prefetch" href="/assets/js/page-GN快速入门.b708bb6a.js"><link rel="prefetch" href="/assets/js/page-Home.97282d71.js"><link rel="prefetch" href="/assets/js/page-HowGNhandlescross-compiling.6ca64957.js"><link rel="prefetch" href="/assets/js/page-Introduction.292088e0.js"><link rel="prefetch" href="/assets/js/page-ninja快速入门.92729e64.js"><link rel="prefetch" href="/assets/js/page-《孙子兵法》全文.402792c5.js"><link rel="prefetch" href="/assets/js/page-《论语》全文.85da0da0.js"><link rel="prefetch" href="/assets/js/page-《诗经》全文.99ebeb52.js"><link rel="prefetch" href="/assets/js/page-《道德经》全文.43627e4e.js"><link rel="prefetch" href="/assets/js/page-两个文档.eb8dd1b7.js"><link rel="prefetch" href="/assets/js/page-主流站点覆盖定期同步更新.1ad02178.js"><link rel="prefetch" href="/assets/js/page-手机版电脑版.b5e8dfea.js"><link rel="prefetch" href="/assets/js/page-捐助方式.6ca91d44.js"><link rel="prefetch" href="/assets/js/page-来源LiteOS和LiteOS-A内核图解.8fa16705.js"><link rel="prefetch" href="/assets/js/page-电脑版手机版.67a0b4a4.js"><link rel="prefetch" href="/assets/js/page-编程语言相关书籍.d9adf7cb.js"><link rel="prefetch" href="/assets/js/page-鸿蒙内核源码分析.bbb451c7.js"><link rel="prefetch" href="/assets/js/vendors~flowchart.46b2de48.js"><link rel="prefetch" href="/assets/js/vendors~mermaid.627fb4be.js"><link rel="prefetch" href="/assets/js/vendors~photo-swipe.cbde97f9.js"><link rel="prefetch" href="/assets/js/vendors~reveal.77b21b7e.js">
    <link rel="stylesheet" href="/assets/css/0.styles.087eb7d3.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container has-navbar has-sidebar has-anchor"><header class="navbar"><!----> <div class="content__navbar-start"></div> <button title="Sidebar Button" class="sidebar-button"><span class="icon"></span></button> <a href="/" class="home-link router-link-active"><!----> <!----> <span class="site-name can-hide">中俊为 | we harmonyos</span></a> <!----> <div class="content__navbar-center"></div> <div class="links"><button tabindex="-1" aria-hidden="true" class="color-button"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="skin-icon"><path d="M224 800c0 9.6 3.2 44.8 6.4 54.4 6.4 48-48 76.8-48 76.8s80 41.6 147.2 0 134.4-134.4
        38.4-195.2c-22.4-12.8-41.6-19.2-57.6-19.2C259.2 716.8 227.2 761.6 224 800zM560 675.2l-32
        51.2c-51.2 51.2-83.2 32-83.2 32 25.6 67.2 0 112-12.8 128 25.6 6.4 51.2 9.6 80 9.6 54.4 0
        102.4-9.6 150.4-32l0 0c3.2 0 3.2-3.2 3.2-3.2 22.4-16 12.8-35.2
        6.4-44.8-9.6-12.8-12.8-25.6-12.8-41.6 0-54.4 60.8-99.2 137.6-99.2 6.4 0 12.8 0 22.4
        0 12.8 0 38.4 9.6 48-25.6 0-3.2 0-3.2 3.2-6.4 0-3.2 3.2-6.4 3.2-6.4 6.4-16 6.4-16 6.4-19.2
        9.6-35.2 16-73.6 16-115.2 0-105.6-41.6-198.4-108.8-268.8C704 396.8 560 675.2 560 675.2zM224
        419.2c0-28.8 22.4-51.2 51.2-51.2 28.8 0 51.2 22.4 51.2 51.2 0 28.8-22.4 51.2-51.2 51.2C246.4
        470.4 224 448 224 419.2zM320 284.8c0-22.4 19.2-41.6 41.6-41.6 22.4 0 41.6 19.2 41.6 41.6 0
        22.4-19.2 41.6-41.6 41.6C339.2 326.4 320 307.2 320 284.8zM457.6 208c0-12.8 12.8-25.6 25.6-25.6
        12.8 0 25.6 12.8 25.6 25.6 0 12.8-12.8 25.6-25.6 25.6C470.4 233.6 457.6 220.8 457.6 208zM128
        505.6C128 592 153.6 672 201.6 736c28.8-60.8 112-60.8 124.8-60.8-16-51.2 16-99.2
        16-99.2l316.8-422.4c-48-19.2-99.2-32-150.4-32C297.6 118.4 128 291.2 128 505.6zM764.8
        86.4c-22.4 19.2-390.4 518.4-390.4 518.4-22.4 28.8-12.8 76.8 22.4 99.2l9.6 6.4c35.2 22.4
        80 12.8 99.2-25.6 0 0 6.4-12.8 9.6-19.2 54.4-105.6 275.2-524.8 288-553.6
        6.4-19.2-3.2-32-19.2-32C777.6 76.8 771.2 80 764.8 86.4z"></path></svg> <div class="color-picker-menu" style="display:none;"><div class="theme-options"><ul class="themecolor-select"><label for="themecolor-select">Theme Color:</label> <li><span class="default-theme"></span></li> </ul> <div class="darkmode-toggle"><label for="darkmode-toggle" class="desc">Theme Mode:</label> <div class="darkmode-switch"><div class="item day"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon light-icon"><path d="M512 256a42.667 42.667 0 0 0 42.667-42.667V128a42.667 42.667 0 0 0-85.334 0v85.333A42.667 42.667 0 0 0 512 256zm384 213.333h-85.333a42.667 42.667 0 0 0 0 85.334H896a42.667 42.667 0 0 0 0-85.334zM256 512a42.667 42.667 0 0 0-42.667-42.667H128a42.667 42.667 0 0 0 0 85.334h85.333A42.667 42.667 0 0 0 256 512zm9.387-298.667a42.667 42.667 0 0 0-59.307 62.72l61.44 59.307a42.667 42.667 0 0 0 31.147 11.947 42.667 42.667 0 0 0 30.72-13.227 42.667 42.667 0 0 0 0-60.16zm459.946 133.974a42.667 42.667 0 0 0 29.44-11.947l61.44-59.307a42.667 42.667 0 0 0-57.6-62.72l-61.44 60.587a42.667 42.667 0 0 0 0 60.16 42.667 42.667 0 0 0 28.16 13.227zM512 768a42.667 42.667 0 0 0-42.667 42.667V896a42.667 42.667 0 0 0 85.334 0v-85.333A42.667 42.667 0 0 0 512 768zm244.48-79.36a42.667 42.667 0 0 0-59.307 61.44l61.44 60.587a42.667 42.667 0 0 0 29.44 11.946 42.667 42.667 0 0 0 30.72-12.8 42.667 42.667 0 0 0 0-60.586zm-488.96 0-61.44 59.307a42.667 42.667 0 0 0 0 60.586 42.667 42.667 0 0 0 30.72 12.8 42.667 42.667 0 0 0 28.587-10.666l61.44-59.307a42.667 42.667 0 0 0-59.307-61.44zM512 341.333A170.667 170.667 0 1 0 682.667 512 170.667 170.667 0 0 0 512 341.333z" fill="currentColor"></path></svg></div> <div class="item auto active"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon auto-icon"><path d="M460.864 539.072H564.8L510.592 376l-49.728 163.072zM872 362.368V149.504H659.648L510.528 0l-149.12 149.504H149.12v212.928L0 511.872l149.12 149.504v212.928h212.352l149.12 149.504 149.12-149.504h212.352V661.376l149.12-149.504L872 362.368zM614.464 693.12l-31.616-90.624H438.272l-31.616 90.624h-85.888l144.576-407.68h90.368l144.576 407.68h-85.824zm0 0" fill="currentColor"></path></svg></div> <div class="item night"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon dark-icon"><path d="M935.539 630.402c-11.43-11.432-28.674-14.739-43.531-8.354-46.734 20.103-96.363 30.297-147.508 30.297-99.59 0-193.221-38.784-263.64-109.203-108.637-108.637-139.61-270.022-78.908-411.148a39.497 39.497 0 0 0-51.886-51.887c-52.637 22.64-100.017 54.81-140.826 95.616-85.346 85.346-132.346 198.821-132.346 319.52 0 120.7 47.001 234.172 132.347 319.519S408.063 947.11 528.76 947.11c120.7 0 234.172-47.003 319.52-132.351 40.809-40.81 72.978-88.19 95.616-140.826a39.497 39.497 0 0 0-8.356-43.532z" fill="currentColor"></path></svg></div></div> <!----></div></div></div></button> <div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link router-link-active"><!---->
  首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="文档中心" class="dropdown-title"><span class="title"><!---->
        文档中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/readme/Readme-CN.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  子系统
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/device-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  南向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://open.weharmonyos.com/zh-cn/application-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  北向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="博客中心" class="dropdown-title"><span class="title"><!---->
        博客中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="/blog/101.html" class="nav-link"><!---->
  总目录
</a></li><li class="dropdown-item"><a href="/blog/index/1_base.html" class="nav-link"><!---->
  基础知识
</a></li><li class="dropdown-item"><a href="/blog/index/2_process.html" class="nav-link"><!---->
  进程管理
</a></li><li class="dropdown-item"><a href="/blog/index/3_task.html" class="nav-link"><!---->
  任务管理
</a></li><li class="dropdown-item"><a href="/blog/index/4_mem.html" class="nav-link"><!---->
  内存管理
</a></li><li class="dropdown-item"><a href="/blog/index/5_ipc.html" class="nav-link"><!---->
  进程通讯
</a></li><li class="dropdown-item"><a href="/blog/index/6_fs.html" class="nav-link"><!---->
  文件系统
</a></li><li class="dropdown-item"><a href="/blog/index/7_hw.html" class="nav-link"><!---->
  软硬接口
</a></li><li class="dropdown-item"><a href="/blog/index/8_asm.html" class="nav-link"><!---->
  内核汇编
</a></li><li class="dropdown-item"><a href="/blog/index/9_run.html" class="nav-link"><!---->
  编译运行
</a></li><li class="dropdown-item"><a href="/blog/index/10_test.html" class="nav-link"><!---->
  调测工具
</a></li><li class="dropdown-item"><a href="/blog/index/0_so.html" class="nav-link"><!---->
  前因后果
</a></li><li class="dropdown-item"><a href="/extsite.html" class="nav-link"><!---->
  前往 &gt;&gt; 外站
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="论坛中心" class="dropdown-title"><span class="title"><!---->
        论坛中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://bbs.weharmonyos.com" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  论坛首页
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="http://bbs.weharmonyos.com/forum-42-1.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  问题建议
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="手册中心" class="dropdown-title"><span class="title"><!---->
        手册中心
      </span> <span class="arrow"></span></button> <ul class="nav-dropdown"><li class="dropdown-item"><a href="http://doxygen.weharmonyos.com/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  内核参考手册
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><a href="/compile/assembly.html" class="nav-link"><!---->
  gnu 汇编教程
</a></li><li class="dropdown-item"><a href="/compile/gn/docs/" class="nav-link"><!---->
  gn 参考手册
</a></li><li class="dropdown-item"><a href="/compile/ninja/Readme-CN.html" class="nav-link"><!---->
  ninja 参考手册
</a></li><li class="dropdown-item"><a href="/compile/fhs.html" class="nav-link"><!---->
  fhs 规范
</a></li></ul></div></div><div class="nav-item"><a href="/donate.html" class="nav-link"><!---->
  赞助中心
</a></div></nav> <!----> <!----> <!----> <div class="content__navbar-end"></div></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><!----> <!----> <div class="content__sidebar-top"></div> <nav class="sidebar-nav-links"><div class="nav-item"><a href="/" class="nav-link router-link-active"><!---->
  首页
</a></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="文档中心" class="dropdown-title"><span class="title"><!---->
      文档中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/readme/Readme-CN.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  子系统
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/device-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  南向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://open.weharmonyos.com/zh-cn/application-dev/website.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  北向
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="博客中心" class="dropdown-title"><span class="title"><!---->
      博客中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/101.html" class="nav-link"><!---->
  总目录
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/1_base.html" class="nav-link"><!---->
  基础知识
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/2_process.html" class="nav-link"><!---->
  进程管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/3_task.html" class="nav-link"><!---->
  任务管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/4_mem.html" class="nav-link"><!---->
  内存管理
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/5_ipc.html" class="nav-link"><!---->
  进程通讯
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/6_fs.html" class="nav-link"><!---->
  文件系统
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/7_hw.html" class="nav-link"><!---->
  软硬接口
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/8_asm.html" class="nav-link"><!---->
  内核汇编
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/9_run.html" class="nav-link"><!---->
  编译运行
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/10_test.html" class="nav-link"><!---->
  调测工具
</a></li><li class="dropdown-item"><!----> <a href="/blog/index/0_so.html" class="nav-link"><!---->
  前因后果
</a></li><li class="dropdown-item"><!----> <a href="/extsite.html" class="nav-link"><!---->
  前往 &gt;&gt; 外站
</a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="论坛中心" class="dropdown-title"><span class="title"><!---->
      论坛中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://bbs.weharmonyos.com" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  论坛首页
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://bbs.weharmonyos.com/forum-42-1.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  问题建议
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="mobile-dropdown-wrapper"><button type="button" aria-label="手册中心" class="dropdown-title"><span class="title"><!---->
      手册中心
    </span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="http://doxygen.weharmonyos.com/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external"><!---->
  内核参考手册
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="/compile/assembly.html" class="nav-link"><!---->
  gnu 汇编教程
</a></li><li class="dropdown-item"><!----> <a href="/compile/gn/docs/" class="nav-link"><!---->
  gn 参考手册
</a></li><li class="dropdown-item"><!----> <a href="/compile/ninja/Readme-CN.html" class="nav-link"><!---->
  ninja 参考手册
</a></li><li class="dropdown-item"><!----> <a href="/compile/fhs.html" class="nav-link"><!---->
  fhs 规范
</a></li></ul></div></div><div class="nav-item"><a href="/donate.html" class="nav-link"><!---->
  赞助中心
</a></div> <!----></nav> <!----> <div class="content__sidebar-center"></div> <ul class="sidebar-links"><li><a href="/blog/101.html" class="sidebar-link">总目录</a></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">基础知识 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">进程管理 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">任务管理 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">内存管理 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable open"><!----> <span class="title">通讯机制 | 14</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/blog/index/5_ipc.html" class="sidebar-link">本章目录</a></li><li><a href="/blog/41.html" class="sidebar-link">通讯总览</a></li><li><a href="/blog/42.html" class="sidebar-link">自旋锁</a></li><li><a href="/blog/43.html" class="sidebar-link">互斥锁</a></li><li><a href="/blog/44.html" class="sidebar-link">快锁使用</a></li><li><a href="/blog/45.html" class="sidebar-link">快锁实现</a></li><li><a href="/blog/46.html" class="sidebar-link">读写锁</a></li><li><a href="/blog/47.html" class="sidebar-link">信号量</a></li><li><a href="/blog/48.html" class="sidebar-link">事件机制</a></li><li><a href="/blog/49.html" class="sidebar-link">信号生产</a></li><li><a href="/blog/50.html" aria-current="page" class="active sidebar-link">信号消费</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/blog/51.html" class="sidebar-link">消息队列</a></li><li><a href="/blog/52.html" class="sidebar-link">消息封装</a></li><li><a href="/blog/53.html" class="sidebar-link">消息映射</a></li><li><a href="/blog/54.html" class="sidebar-link">共享内存</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">文件系统 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">硬件架构 | 9</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">内核汇编 | 10</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">编译运行 | 13</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">调测工具 | 4</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading clickable"><!----> <span class="title">前因后果 | 4</span> <span class="arrow right"></span></p> <!----></section></li></ul> <!----> <div class="content__sidebar-bottom"></div> <!----></aside> <main class="page"><nav class="breadcrumb disable"><!----></nav> <!----> <div class="content__page-top"></div> <div vocab="https://schema.org/" typeof="Article" class="page-title"><h1><!----> <span property="headline"></span></h1> <div class="page-info"><!----> </div> <!----> <hr></div> <div class="anchor-place-holder"><aside id="anchor"><div class="anchor-wrapper"><ul class="anchor-list"><li class="anchor"><a href="/blog/50.html#信号消费" class="anchor-link heading3"><div>信号消费</div></a></li><li class="anchor"><a href="/blog/50.html#sig-switch-context" class="anchor-link heading3"><div>sigswitchcontext</div></a></li><li class="anchor"><a href="/blog/50.html#osarma32syscallhandle-系统调用总入口" class="anchor-link heading3"><div>OsArmA32SyscallHandle 系统调用总入口</div></a></li><li class="anchor"><a href="/blog/50.html#ossavesignalcontext-保存信号上下文" class="anchor-link heading3"><div>OsSaveSignalContext 保存信号上下文</div></a></li><li class="anchor"><a href="/blog/50.html#osrestorsignalcontext-恢复信号上下文" class="anchor-link heading3"><div>OsRestorSignalContext 恢复信号上下文</div></a></li><li class="anchor"><a href="/blog/50.html#百文说内核-抓住主脉络" class="anchor-link heading3"><div>百文说内核 | 抓住主脉络</div></a></li><li class="anchor"><a href="/blog/50.html#百万注源码-处处扣细节" class="anchor-link heading3"><div>百万注源码 | 处处扣细节</div></a></li><li class="anchor"><a href="/blog/50.html#关注不迷路-代码即人生" class="anchor-link heading3"><div>关注不迷路 | 代码即人生</div></a></li></ul></div></aside></div> <!----> <div class="content__content-top"></div> <div class="theme-default-content content__default"><p>本篇关键词：、、、</p> <p><a href="https://weharmony.gitee.io/blog/50.html" target="_blank" rel="noopener noreferrer"><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/index/50.png" alt=""></a></p> <p><a href="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/pdf/%E9%B8%BF%E8%92%99%E5%86%85%E6%A0%B8%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90(%E7%99%BE%E7%AF%87%E5%8D%9A%E5%AE%A2%E5%88%86%E6%9E%90.%E6%8C%96%E9%80%8F%E9%B8%BF%E8%92%99%E5%86%85%E6%A0%B8).zip" target="_blank" rel="noopener noreferrer">下载 &gt;&gt; 离线文档.鸿蒙内核源码分析(百篇博客分析.挖透鸿蒙内核).pdf</a></p> <p>通讯机制相关篇为:</p> <ul><li><a href="http://weharmonyos.com/blog/41.html" target="_blank" rel="noopener noreferrer">v41.04 鸿蒙内核源码分析(通讯总览) | 内核跟人一样都喜欢八卦</a></li> <li><a href="http://weharmonyos.com/blog/42.html" target="_blank" rel="noopener noreferrer">v42.08 鸿蒙内核源码分析(自旋锁) | 死等丈夫归来的贞洁烈女</a></li> <li><a href="http://weharmonyos.com/blog/43.html" target="_blank" rel="noopener noreferrer">v43.05 鸿蒙内核源码分析(互斥锁) | 有你没她 相安无事</a></li> <li><a href="http://weharmonyos.com/blog/44.html" target="_blank" rel="noopener noreferrer">v44.02 鸿蒙内核源码分析(快锁使用) | 用户态负责快锁逻辑</a></li> <li><a href="http://weharmonyos.com/blog/45.html" target="_blank" rel="noopener noreferrer">v45.02 鸿蒙内核源码分析(快锁实现) | 内核态负责快锁调度</a></li> <li><a href="http://weharmonyos.com/blog/46.html" target="_blank" rel="noopener noreferrer">v46.01 鸿蒙内核源码分析(读写锁) | 内核如何实现多读单写</a></li> <li><a href="http://weharmonyos.com/blog/47.html" target="_blank" rel="noopener noreferrer">v47.05 鸿蒙内核源码分析(信号量) | 谁在解决任务间的同步</a></li> <li><a href="http://weharmonyos.com/blog/48.html" target="_blank" rel="noopener noreferrer">v48.07 鸿蒙内核源码分析(事件机制) | 多对多任务如何同步</a></li> <li><a href="http://weharmonyos.com/blog/49.html" target="_blank" rel="noopener noreferrer">v49.05 鸿蒙内核源码分析(信号生产) | 年过半百 活力十足</a></li> <li><a href="http://weharmonyos.com/blog/50.html" target="_blank" rel="noopener noreferrer">v50.03 鸿蒙内核源码分析(信号消费) | 谁让CPU连续四次换栈运行</a></li> <li><a href="http://weharmonyos.com/blog/51.html" target="_blank" rel="noopener noreferrer">v51.03 鸿蒙内核源码分析(消息队列) | 进程间如何异步传递大数据</a></li> <li><a href="http://weharmonyos.com/blog/52.html" target="_blank" rel="noopener noreferrer">v52.02 鸿蒙内核源码分析(消息封装) | 剖析LiteIpc(上)进程通讯内容</a></li> <li><a href="http://weharmonyos.com/blog/53.html" target="_blank" rel="noopener noreferrer">v53.01 鸿蒙内核源码分析(消息映射) | 剖析LiteIpc(下)进程通讯机制</a></li> <li><a href="http://weharmonyos.com/blog/54.html" target="_blank" rel="noopener noreferrer">v54.01 鸿蒙内核源码分析(共享内存) | 进程间最快通讯方式</a></li></ul> <h3 id="信号消费">信号消费</h3> <p>本篇为信号消费篇，读之前建议先阅读信号生产篇，信号部分姊妹篇如下:</p> <ul><li><strong>v49.xx (信号生产篇) | 年过半百，依然活力十足</strong></li> <li><strong>v50.xx (信号消费篇) | 谁让CPU连续四次换栈运行</strong></li></ul> <p>本篇有相当的难度，涉及用户栈和内核栈的两轮切换，CPU四次换栈，寄存器改值，将围绕下图来说明。
<img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/49/signal_handle.png" alt=""></p> <p><strong>解读</strong></p> <ul><li>为本篇理解方便，把图做简化标签说明:
<ul><li>user:用户空间</li> <li>kernel:内核空间</li> <li>source(...):源函数</li> <li>sighandle(...):信号处理函数，</li> <li>syscall(...):系统调用，参数为系统调用号，如sigreturn，N(表任意)</li> <li>user.source():表示在用户空间运行的源函数</li></ul></li> <li>系列篇已多次说过，用户态的任务有两个运行栈，一个是用户栈，一个是内核栈。栈空间分别来自用户空间和内核空间。两种空间是有严格的地址划分的，通过虚拟地址的大小就能判断出是用户空间还是内核空间。系统调用本质上是软中断，它使CPU执行指令的场地由用户栈变成内核栈。怎么变的并不复杂，就是改变(sp和cpsr寄存器的值)。sp指向哪个栈就代表在哪个栈运行， 当cpu在用户栈运行时是不能访问内核空间的，但内核态任务可以访问整个空间，而且内核态任务没有用户栈。</li> <li>理解了上面的说明，再来说下正常系统调用流程是这样的: user.source() -&gt; kernel。syscall(N) - &gt; user.source() ，想要回到user.source()继续运行，就必须保存用户栈现场各寄存器的值。这些值保存在内核栈中，恢复也是从内核栈恢复。</li> <li>信号消费的过程的上图可简化表示为: user.source() -&gt; kernel。syscall(N) -&gt;user。sighandle() -&gt;kernel。syscall(sigreturn) -&gt; user.source() 在原本要回到user.source()的中间插入了信号处理函数的调用。 这正是本篇要通过代码来说清楚的核心问题。</li> <li>顺着这个思路可以推到以下几点，实际也是这么做的:
<ul><li><p>kernel。syscall(N) 中必须要再次保存user.source()的上下文<code>sig_switch_context</code>，为何已经保存了一次还要再保存一次？</p></li> <li><p>因为第一次是保存在内核栈中，而内核栈这部分数据会因回到用户态user。sighandle()运行而被恢复现场出栈了。保存现场/恢复现场是成双出队的好基友，注意有些文章说会把整个内核栈清空，这是不对的。</p></li> <li><p>第二次保存在任务结构体中，任务来源于任务池，是内核全局变量，常驻内存的。两次保存的都是user.source()运行时现场信息，再回顾下相关的结构体。关键是<code>sig_switch_context</code></p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    <span class="token comment">// ...</span>
    sig_cb  sig<span class="token punctuation">;</span><span class="token comment">//信号控制块，用于异步通信</span>
<span class="token punctuation">}</span> LosTaskCB<span class="token punctuation">;</span>
<span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token punctuation">{</span><span class="token comment">//信号控制块(描述符)</span>
    <span class="token class-name">sigset_t</span> sigFlag<span class="token punctuation">;</span>		<span class="token comment">//不屏蔽的信号集</span>
    <span class="token class-name">sigset_t</span> sigPendFlag<span class="token punctuation">;</span>	<span class="token comment">//信号阻塞标签集，记录那些信号来过，任务依然阻塞的集合。即:这些信号不能唤醒任务</span>
    <span class="token class-name">sigset_t</span> sigprocmask<span class="token punctuation">;</span> <span class="token comment">/* Signals that are blocked            */</span>	<span class="token comment">//任务屏蔽了哪些信号</span>
    <span class="token class-name">sq_queue_t</span> sigactionq<span class="token punctuation">;</span>	<span class="token comment">//信号捕捉队列					</span>
    LOS_DL_LIST waitList<span class="token punctuation">;</span>	<span class="token comment">//等待链表，上面挂的是等待信号到来的任务， 请查找 OsTaskWait(&amp;sigcb-&gt;waitList， timeout， TRUE)	理解						</span>
    <span class="token class-name">sigset_t</span> sigwaitmask<span class="token punctuation">;</span> <span class="token comment">/* Waiting for pending signals         */</span>	<span class="token comment">//任务在等待哪些信号的到来</span>
    <span class="token class-name">siginfo_t</span> sigunbinfo<span class="token punctuation">;</span> <span class="token comment">/* Signal info when task unblocked     */</span>	<span class="token comment">//任务解锁时的信号信息</span>
    sig_switch_context context<span class="token punctuation">;</span>	<span class="token comment">//信号切换上下文， 用于保存切换现场， 比如发生系统调用时的返回，涉及同一个任务的两个栈进行切换			</span>
<span class="token punctuation">}</span> sig_cb<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div></li> <li><p>还必须要改变原有PC/R0/R1寄存器的值。想要执行user。sighandle()，PC寄存器就必须指向它，而R0，R1就是它的参数。</p></li> <li><p>信号处理完成后须回到内核态，怎么再次陷入内核态？ 答案是:<code>__NR_sigreturn</code>，这也是个系统调用。回来后还原<code>sig_switch_context</code>，即还原user.source()被打断时SP/PC等寄存器的值，使其跳回到用户栈从user.source()的被打断处继续执行。</p></li></ul></li> <li>有了这三个推论，再理解下面的代码就是吹灰之力了，涉及三个关键函数 <code>OsArmA32SyscallHandle</code>，<code>OsSaveSignalContext</code>，<code>OsRestorSignalContext</code>本篇一一解读，彻底挖透。先看信号上下文结构体<code>sig_switch_context</code>。</li></ul> <h3 id="sig-switch-context">sig_switch_context</h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//任务中断上下文</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">TASK_IRQ_CONTEXT</span> <span class="token punctuation">\</span>
        <span class="token expression"><span class="token keyword">unsigned</span> <span class="token keyword">int</span> R0<span class="token punctuation">;</span>     </span><span class="token punctuation">\</span>
        <span class="token expression"><span class="token keyword">unsigned</span> <span class="token keyword">int</span> R1<span class="token punctuation">;</span>     </span><span class="token punctuation">\</span>
        <span class="token expression"><span class="token keyword">unsigned</span> <span class="token keyword">int</span> R2<span class="token punctuation">;</span>     </span><span class="token punctuation">\</span>
        <span class="token expression"><span class="token keyword">unsigned</span> <span class="token keyword">int</span> R3<span class="token punctuation">;</span>     </span><span class="token punctuation">\</span>
        <span class="token expression"><span class="token keyword">unsigned</span> <span class="token keyword">int</span> R12<span class="token punctuation">;</span>    </span><span class="token punctuation">\</span>
        <span class="token expression"><span class="token keyword">unsigned</span> <span class="token keyword">int</span> USP<span class="token punctuation">;</span>    </span><span class="token punctuation">\</span>
        <span class="token expression"><span class="token keyword">unsigned</span> <span class="token keyword">int</span> ULR<span class="token punctuation">;</span>    </span><span class="token punctuation">\</span>
        <span class="token expression"><span class="token keyword">unsigned</span> <span class="token keyword">int</span> CPSR<span class="token punctuation">;</span>   </span><span class="token punctuation">\</span>
        <span class="token expression"><span class="token keyword">unsigned</span> <span class="token keyword">int</span> PC<span class="token punctuation">;</span></span></span>

<span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token punctuation">{</span><span class="token comment">//信号切换上下文</span>
    TASK_IRQ_CONTEXT
    <span class="token keyword">unsigned</span> <span class="token keyword">int</span> R7<span class="token punctuation">;</span>	<span class="token comment">//存放系统调用的ID</span>
    <span class="token keyword">unsigned</span> <span class="token keyword">int</span> count<span class="token punctuation">;</span>	<span class="token comment">//记录是否保存了信号上下文</span>
<span class="token punctuation">}</span> sig_switch_context<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><ul><li>保存user.source()现场的结构体，<code>USP</code>，<code>ULR</code>代表用户栈指针和返回地址。</li> <li><code>CPSR</code>寄存器用于设置CPU的工作模式，CPU有7种工作模式，具体可前往翻看 v36。xx (工作模式篇)谈论的用户态(<code>usr</code>普通用户)和内核态(<code>sys</code>超级用户)对应的只是其中的两种。二者都共用相同的寄存器。还原它就是告诉CPU内核已切到普通用户模式运行。</li> <li>其他寄存器没有保存的原因是系统调用不会用到它们，所以不需要保存。</li> <li><code>R7</code>是在系统调用发生时用于记录系统调用号，在信号处理过程中，R0将获得信号编号，作为user。sighandle()的第一个参数。</li> <li><code>count</code>记录是否保存了信号上下文</li></ul> <h3 id="osarma32syscallhandle-系统调用总入口">OsArmA32SyscallHandle 系统调用总入口</h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">/* The SYSCALL ID is in R7 on entry。  Parameters follow in R0。。R6 */</span>
<span class="token comment">/******************************************************************
由汇编调用，见于 los_hw_exc.S    / BLX    OsArmA32SyscallHandle
SYSCALL是产生系统调用时触发的信号，R7寄存器存放具体的系统调用ID，也叫系统调用号
regs:参数就是所有寄存器
注意:本函数在用户态和内核态下都可能被调用到
//MOV     R0， SP @获取SP值，R0将作为OsArmA32SyscallHandle的参数
******************************************************************/</span>
LITE_OS_SEC_TEXT UINT32 <span class="token operator">*</span><span class="token function">OsArmA32SyscallHandle</span><span class="token punctuation">(</span>UINT32 <span class="token operator">*</span>regs<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    UINT32 ret<span class="token punctuation">;</span>
    UINT8 nArgs<span class="token punctuation">;</span>
    UINTPTR handle<span class="token punctuation">;</span>
    UINT32 cmd <span class="token operator">=</span> regs<span class="token punctuation">[</span>REG_R7<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">//C7寄存器记录了触发了具体哪个系统调用</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>cmd <span class="token operator">&gt;=</span> SYS_CALL_NUM<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//系统调用的总数</span>
        <span class="token function">PRINT_ERR</span><span class="token punctuation">(</span><span class="token string">&quot;Syscall ID: error %d !!!\n&quot;</span>， cmd<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> regs<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
	<span class="token comment">//用户进程信号处理函数完成后的系统调用 svc 119 #__NR_sigreturn</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>cmd <span class="token operator">==</span> __NR_sigreturn<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">OsRestorSignalContext</span><span class="token punctuation">(</span>regs<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//恢复信号上下文，回到用户栈运行。</span>
        <span class="token keyword">return</span> regs<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    handle <span class="token operator">=</span> g_syscallHandle<span class="token punctuation">[</span>cmd<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">//拿到系统调用的注册函数，类似 SysRead </span>
    nArgs <span class="token operator">=</span> g_syscallNArgs<span class="token punctuation">[</span>cmd <span class="token operator">/</span> NARG_PER_BYTE<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">/* 4bit per nargs */</span>
    nArgs <span class="token operator">=</span> <span class="token punctuation">(</span>cmd <span class="token operator">&amp;</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">?</span><span class="token punctuation">(</span>nArgs <span class="token operator">&gt;&gt;</span> NARG_BITS<span class="token punctuation">)</span><span class="token operator">:</span><span class="token punctuation">(</span>nArgs <span class="token operator">&amp;</span> NARG_MASK<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//获取参数个数</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>handle <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">(</span>nArgs <span class="token operator">&gt;</span> ARG_NUM_7<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//系统调用必须有参数且参数不能大于8个</span>
        <span class="token function">PRINT_ERR</span><span class="token punctuation">(</span><span class="token string">&quot;Unsupport syscall ID: %d nArgs: %d\n&quot;</span>， cmd， nArgs<span class="token punctuation">)</span><span class="token punctuation">;</span>
        regs<span class="token punctuation">[</span>REG_R0<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span>ENOSYS<span class="token punctuation">;</span>
        <span class="token keyword">return</span> regs<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
	<span class="token comment">//regs[0-6] 记录系统调用的参数，这也是由R7寄存器保存系统调用号的原因</span>
    <span class="token keyword">switch</span> <span class="token punctuation">(</span>nArgs<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//参数的个数 </span>
        <span class="token keyword">case</span> ARG_NUM_0<span class="token operator">:</span>
        <span class="token keyword">case</span> ARG_NUM_1<span class="token operator">:</span>
            ret <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span>SyscallFun1<span class="token punctuation">)</span>handle<span class="token punctuation">)</span><span class="token punctuation">(</span>regs<span class="token punctuation">[</span>REG_R0<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//执行系统调用，类似 SysUnlink(pathname);</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> ARG_NUM_2<span class="token operator">:</span><span class="token comment">//如何是两个参数的系统调用，这里传三个参数也没有问题，因被调用函数不会去取用R2值</span>
        <span class="token keyword">case</span> ARG_NUM_3<span class="token operator">:</span>
            ret <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span>SyscallFun3<span class="token punctuation">)</span>handle<span class="token punctuation">)</span><span class="token punctuation">(</span>regs<span class="token punctuation">[</span>REG_R0<span class="token punctuation">]</span>， regs<span class="token punctuation">[</span>REG_R1<span class="token punctuation">]</span>， regs<span class="token punctuation">[</span>REG_R2<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//类似 SysExecve(fileName， argv， envp);</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> ARG_NUM_4<span class="token operator">:</span>
        <span class="token keyword">case</span> ARG_NUM_5<span class="token operator">:</span>
            ret <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span>SyscallFun5<span class="token punctuation">)</span>handle<span class="token punctuation">)</span><span class="token punctuation">(</span>regs<span class="token punctuation">[</span>REG_R0<span class="token punctuation">]</span>， regs<span class="token punctuation">[</span>REG_R1<span class="token punctuation">]</span>， regs<span class="token punctuation">[</span>REG_R2<span class="token punctuation">]</span>， regs<span class="token punctuation">[</span>REG_R3<span class="token punctuation">]</span>，
                                         regs<span class="token punctuation">[</span>REG_R4<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">default</span><span class="token operator">:</span>	<span class="token comment">//7个参数的情况</span>
            ret <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span>SyscallFun7<span class="token punctuation">)</span>handle<span class="token punctuation">)</span><span class="token punctuation">(</span>regs<span class="token punctuation">[</span>REG_R0<span class="token punctuation">]</span>， regs<span class="token punctuation">[</span>REG_R1<span class="token punctuation">]</span>， regs<span class="token punctuation">[</span>REG_R2<span class="token punctuation">]</span>， regs<span class="token punctuation">[</span>REG_R3<span class="token punctuation">]</span>，
                                         regs<span class="token punctuation">[</span>REG_R4<span class="token punctuation">]</span>， regs<span class="token punctuation">[</span>REG_R5<span class="token punctuation">]</span>， regs<span class="token punctuation">[</span>REG_R6<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    regs<span class="token punctuation">[</span>REG_R0<span class="token punctuation">]</span> <span class="token operator">=</span> ret<span class="token punctuation">;</span><span class="token comment">//R0保存系统调用返回值</span>
    <span class="token function">OsSaveSignalContext</span><span class="token punctuation">(</span>regs<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//如果有信号要处理，将改写pc，r0，r1寄存器，改变返回正常用户态路径，而先去执行信号处理程序。</span>
    <span class="token comment">/* Return the last value of curent_regs。  This supports context switches on return from the exception。
     * That capability is only used with the SYS_context_switch system call。
     */</span>
    <span class="token keyword">return</span> regs<span class="token punctuation">;</span><span class="token comment">//返回寄存器的值</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br></div></div><p><strong>解读</strong></p> <ul><li>这是系统调用的总入口，所有的系统调用都要跑这里要统一处理。通过系统号(保存在R7)，找到注册函数并回调。完成系统调用过程。</li> <li>关于系统调用可查看
<a href="https://my.oschina.net/weharmony/blog/4967613" target="_blank" rel="noopener noreferrer">v37。xx (系统调用篇) | 系统调用到底经历了什么 </a>
本篇不详细说系统调用过程，只说跟信号相关的部分。</li> <li><code>OsArmA32SyscallHandle</code>总体理解起来是被信号的保存和还原两个函数给包夹了。注意要在运行过程中去理解调用两个函数的过程，对于同一个任务来说，一定是先执行<code>OsSaveSignalContext</code>，第二次进入<code>OsArmA32SyscallHandle</code>后再执行<code>OsRestorSignalContext</code>。</li> <li>看<code>OsSaveSignalContext</code>，由它负责保存user.source() 的上下文，其中改变了sp，r0/r1寄存器值，切到信号处理函数user。sighandle()运行。</li> <li>在函数的开头，碰到系统调用号<code>__NR_sigreturn</code>，直接恢复信号上下文就退出了，因为这是要切回user.source()继续运行的操作。</li></ul> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//用户进程信号处理函数完成后的系统调用 svc 119 #__NR_sigreturn</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>cmd <span class="token operator">==</span> __NR_sigreturn<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">OsRestorSignalContext</span><span class="token punctuation">(</span>regs<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//恢复信号上下文，回到用户栈运行。</span>
    <span class="token keyword">return</span> regs<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h3 id="ossavesignalcontext-保存信号上下文">OsSaveSignalContext 保存信号上下文</h3> <p>有了上面的铺垫，就不难理解这个函数的作用。</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">/**********************************************
产生系统调用时，也就是软中断时，保存用户栈寄存器现场信息
改写PC寄存器的值
**********************************************/</span>
<span class="token keyword">void</span> <span class="token function">OsSaveSignalContext</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> <span class="token operator">*</span>sp<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    UINTPTR sigHandler<span class="token punctuation">;</span>
    UINT32 intSave<span class="token punctuation">;</span>
    LosTaskCB <span class="token operator">*</span>task <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    LosProcessCB <span class="token operator">*</span>process <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    sig_cb <span class="token operator">*</span>sigcb <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    <span class="token keyword">unsigned</span> <span class="token keyword">long</span> cpsr<span class="token punctuation">;</span>
    <span class="token function">OS_RETURN_IF_VOID</span><span class="token punctuation">(</span>sp <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    cpsr <span class="token operator">=</span> <span class="token function">OS_SYSCALL_GET_CPSR</span><span class="token punctuation">(</span>sp<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//获取系统调用时的 CPSR值</span>
    <span class="token function">OS_RETURN_IF_VOID</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>cpsr <span class="token operator">&amp;</span> CPSR_MASK_MODE<span class="token punctuation">)</span> <span class="token operator">!=</span> CPSR_USER_MODE<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//必须工作在CPU的用户模式下，注意CPSR_USER_MODE(cpu层面)和OS_USER_MODE(系统层面)是两码事。</span>
    <span class="token function">SCHEDULER_LOCK</span><span class="token punctuation">(</span>intSave<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//如有不明白前往 https://my.oschina.net/weharmony 翻看工作模式/信号分发/信号处理篇</span>
    task <span class="token operator">=</span> <span class="token function">OsCurrTaskGet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    process <span class="token operator">=</span> <span class="token function">OsCurrProcessGet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    sigcb <span class="token operator">=</span> <span class="token operator">&amp;</span>task<span class="token operator">-&gt;</span>sig<span class="token punctuation">;</span><span class="token comment">//获取任务的信号控制块</span>
	<span class="token comment">//1。未保存任务上下文任务</span>
	<span class="token comment">//2。任何的信号标签集不为空或者进程有信号要处理</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>count <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>sigcb<span class="token operator">-&gt;</span>sigFlag <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">(</span>process<span class="token operator">-&gt;</span>sigShare <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        sigHandler <span class="token operator">=</span> <span class="token function">OsGetSigHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//获取信号处理函数</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>sigHandler <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//信号没有注册</span>
            sigcb<span class="token operator">-&gt;</span>sigFlag <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
            process<span class="token operator">-&gt;</span>sigShare <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token function">SCHEDULER_UNLOCK</span><span class="token punctuation">(</span>intSave<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token function">PRINT_ERR</span><span class="token punctuation">(</span><span class="token string">&quot;The signal processing function for the current process pid =%d is NULL!\n&quot;</span>， task<span class="token operator">-&gt;</span>processID<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token comment">/* One pthread do the share signal */</span> 
        sigcb<span class="token operator">-&gt;</span>sigFlag <span class="token operator">|=</span> process<span class="token operator">-&gt;</span>sigShare<span class="token punctuation">;</span><span class="token comment">//扩展任务的信号标签集</span>
        <span class="token keyword">unsigned</span> <span class="token keyword">int</span> signo <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token punctuation">)</span><span class="token function">FindFirstSetedBit</span><span class="token punctuation">(</span>sigcb<span class="token operator">-&gt;</span>sigFlag<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
        <span class="token function">OsProcessExitCodeSignalSet</span><span class="token punctuation">(</span>process， signo<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//设置进程退出信号</span>
        sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>CPSR <span class="token operator">=</span> cpsr<span class="token punctuation">;</span>		<span class="token comment">//保存状态寄存器</span>
        sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>PC <span class="token operator">=</span> sp<span class="token punctuation">[</span>REG_PC<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">//获取被打断现场寄存器的值</span>
        sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>USP <span class="token operator">=</span> sp<span class="token punctuation">[</span>REG_SP<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">//用户栈顶位置，以便能从内核栈切回用户栈</span>
        sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>ULR <span class="token operator">=</span> sp<span class="token punctuation">[</span>REG_LR<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">//用户栈返回地址</span>
        sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R0 <span class="token operator">=</span> sp<span class="token punctuation">[</span>REG_R0<span class="token punctuation">]</span><span class="token punctuation">;</span>	<span class="token comment">//系统调用的返回值</span>
        sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R1 <span class="token operator">=</span> sp<span class="token punctuation">[</span>REG_R1<span class="token punctuation">]</span><span class="token punctuation">;</span>
        sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R2 <span class="token operator">=</span> sp<span class="token punctuation">[</span>REG_R2<span class="token punctuation">]</span><span class="token punctuation">;</span>
        sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R3 <span class="token operator">=</span> sp<span class="token punctuation">[</span>REG_R3<span class="token punctuation">]</span><span class="token punctuation">;</span> 
        sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R7 <span class="token operator">=</span> sp<span class="token punctuation">[</span>REG_R7<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">//为何参数不用传R7，是因为系统调用发生时 R7始终保存的是系统调用号。</span>
        sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R12 <span class="token operator">=</span> sp<span class="token punctuation">[</span>REG_R12<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">//详见 https://my.oschina.net/weharmony/blog/4967613</span>
        sp<span class="token punctuation">[</span>REG_PC<span class="token punctuation">]</span> <span class="token operator">=</span> sigHandler<span class="token punctuation">;</span><span class="token comment">//指定信号执行函数，注意此处改变保存任务上下文中PC寄存器的值，恢复上下文时将执行这个函数。</span>
        sp<span class="token punctuation">[</span>REG_R0<span class="token punctuation">]</span> <span class="token operator">=</span> signo<span class="token punctuation">;</span>		<span class="token comment">//参数1，信号ID</span>
        sp<span class="token punctuation">[</span>REG_R1<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">(</span>UINTPTR<span class="token punctuation">)</span><span class="token punctuation">(</span>sigcb<span class="token operator">-&gt;</span>sigunbinfo。si_value。sival_ptr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//参数2</span>
        <span class="token comment">/* sig No bits 00000100 present sig No 3， but  1&lt;&lt; 3 = 00001000， so signo needs minus 1 */</span>
        sigcb<span class="token operator">-&gt;</span>sigFlag <span class="token operator">^=</span> <span class="token number">1ULL</span> <span class="token operator">&lt;&lt;</span> <span class="token punctuation">(</span>signo <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>count<span class="token operator">++</span><span class="token punctuation">;</span>	<span class="token comment">//代表已保存</span>
    <span class="token punctuation">}</span>
    <span class="token function">SCHEDULER_UNLOCK</span><span class="token punctuation">(</span>intSave<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br></div></div><p><strong>解读</strong></p> <ul><li><p>先是判断执行条件，确实是有信号需要处理，有处理函数。自定义处理函数是由用户进程安装进来的，所有进程旗下的任务都共用，参数就是信号<code>signo</code>，注意可不是系统调用号，有区别的。信号编号长这样。</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SIGHUP</span>    <span class="token expression"><span class="token number">1</span>	</span><span class="token comment">//终端挂起或者控制进程终止</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SIGINT</span>    <span class="token expression"><span class="token number">2</span>	</span><span class="token comment">//键盘中断（ctrl + c）</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SIGQUIT</span>   <span class="token expression"><span class="token number">3</span>	</span><span class="token comment">//键盘的退出键被按下</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SIGILL</span>    <span class="token expression"><span class="token number">4</span>	</span><span class="token comment">//非法指令</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SIGTRAP</span>   <span class="token expression"><span class="token number">5</span>	</span><span class="token comment">//跟踪陷阱（trace trap），启动进程，跟踪代码的执行</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SIGABRT</span>   <span class="token expression"><span class="token number">6</span>	</span><span class="token comment">//由abort(3)发出的退出指令</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SIGIOT</span>    <span class="token expression">SIGABRT </span><span class="token comment">//abort发出的信号</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SIGBUS</span>    <span class="token expression"><span class="token number">7</span>	</span><span class="token comment">//总线错误 </span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SIGFPE</span>    <span class="token expression"><span class="token number">8</span>	</span><span class="token comment">//浮点异常</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SIGKILL</span>   <span class="token expression"><span class="token number">9</span>	</span><span class="token comment">//常用的命令 kill 9 123 | 不能被忽略、处理和阻塞</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>系统调用号长这样，是不是看到一些很熟悉的函数。</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_restart_syscall</span> <span class="token expression"><span class="token number">0</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_exit</span> <span class="token expression"><span class="token number">1</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_fork</span> <span class="token expression"><span class="token number">2</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_read</span> <span class="token expression"><span class="token number">3</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_write</span> <span class="token expression"><span class="token number">4</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_open</span> <span class="token expression"><span class="token number">5</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_close</span> <span class="token expression"><span class="token number">6</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_waitpid</span> <span class="token expression"><span class="token number">7</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_creat</span> <span class="token expression"><span class="token number">8</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_link</span> <span class="token expression"><span class="token number">9</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_unlink</span> <span class="token expression"><span class="token number">10</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_execve</span> <span class="token expression"><span class="token number">11</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_chdir</span> <span class="token expression"><span class="token number">12</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_time</span> <span class="token expression"><span class="token number">13</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_mknod</span> <span class="token expression"><span class="token number">14</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_chmod</span> <span class="token expression"><span class="token number">15</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_lchown</span> <span class="token expression"><span class="token number">16</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_break</span> <span class="token expression"><span class="token number">17</span></span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div></li> <li><p>最后是最最最关键的代码，改变pc寄存器的值，此值一变，在<code>_osExceptSwiHdl</code>中恢复上下文后，cpu跳到用户空间的代码段 user。sighandle(R0，R1) 开始执行，即执行信号处理函数。</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>sp<span class="token punctuation">[</span>REG_PC<span class="token punctuation">]</span> <span class="token operator">=</span> sigHandler<span class="token punctuation">;</span><span class="token comment">//指定信号执行函数，注意此处改变保存任务上下文中PC寄存器的值，恢复上下文时将执行这个函数。</span>
sp<span class="token punctuation">[</span>REG_R0<span class="token punctuation">]</span> <span class="token operator">=</span> signo<span class="token punctuation">;</span>		<span class="token comment">//参数1，信号ID</span>
sp<span class="token punctuation">[</span>REG_R1<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">(</span>UINTPTR<span class="token punctuation">)</span><span class="token punctuation">(</span>sigcb<span class="token operator">-&gt;</span>sigunbinfo。si_value。sival_ptr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//参数2</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div></li></ul> <h3 id="osrestorsignalcontext-恢复信号上下文">OsRestorSignalContext 恢复信号上下文</h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">/****************************************************
恢复信号上下文，由系统调用之__NR_sigreturn产生，这是一个内部产生的系统调用。
为什么要恢复呢？
因为系统调用的执行由任务内核态完成，使用的栈也是内核栈，CPU相关寄存器记录的都是内核栈的内容，
而系统调用完成后，需返回任务的用户栈执行，这时需将CPU各寄存器回到用户态现场
所以函数的功能就变成了还原寄存器的值
****************************************************/</span>
<span class="token keyword">void</span> <span class="token function">OsRestorSignalContext</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> <span class="token operator">*</span>sp<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    LosTaskCB <span class="token operator">*</span>task <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span> <span class="token comment">/* Do not adjust this statement */</span>
    LosProcessCB <span class="token operator">*</span>process <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    sig_cb <span class="token operator">*</span>sigcb <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    UINT32 intSave<span class="token punctuation">;</span>
    <span class="token function">SCHEDULER_LOCK</span><span class="token punctuation">(</span>intSave<span class="token punctuation">)</span><span class="token punctuation">;</span>
    task <span class="token operator">=</span> <span class="token function">OsCurrTaskGet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    sigcb <span class="token operator">=</span> <span class="token operator">&amp;</span>task<span class="token operator">-&gt;</span>sig<span class="token punctuation">;</span><span class="token comment">//获取当前任务信号控制块</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>count <span class="token operator">!=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//必须之前保存过，才能被恢复</span>
        <span class="token function">SCHEDULER_UNLOCK</span><span class="token punctuation">(</span>intSave<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">PRINT_ERR</span><span class="token punctuation">(</span><span class="token string">&quot;sig error count : %d\n&quot;</span>， sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>count<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    process <span class="token operator">=</span> <span class="token function">OsCurrProcessGet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//获取当前进程</span>
    sp<span class="token punctuation">[</span>REG_PC<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>PC<span class="token punctuation">;</span><span class="token comment">//指令寄存器</span>
    <span class="token function">OS_SYSCALL_SET_CPSR</span><span class="token punctuation">(</span>sp， sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>CPSR<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//重置程序状态寄存器</span>
    sp<span class="token punctuation">[</span>REG_SP<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>USP<span class="token punctuation">;</span><span class="token comment">//用户栈堆栈指针， USP指的是 用户态的堆栈，即将回到用户栈继续运行</span>
    sp<span class="token punctuation">[</span>REG_LR<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>ULR<span class="token punctuation">;</span><span class="token comment">//返回用户栈代码执行位置</span>
    sp<span class="token punctuation">[</span>REG_R0<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R0<span class="token punctuation">;</span>
    sp<span class="token punctuation">[</span>REG_R1<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R1<span class="token punctuation">;</span>
    sp<span class="token punctuation">[</span>REG_R2<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R2<span class="token punctuation">;</span>
    sp<span class="token punctuation">[</span>REG_R3<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R3<span class="token punctuation">;</span>
    sp<span class="token punctuation">[</span>REG_R7<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R7<span class="token punctuation">;</span>
    sp<span class="token punctuation">[</span>REG_R12<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>R12<span class="token punctuation">;</span>
    sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>count<span class="token operator">--</span><span class="token punctuation">;</span>	<span class="token comment">//信号上下文的数量回到减少</span>
    process<span class="token operator">-&gt;</span>sigShare <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>	<span class="token comment">//回到用户态，信号共享清0</span>
    <span class="token function">OsProcessExitCodeSignalClear</span><span class="token punctuation">(</span>process<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//清空进程退出码</span>
    <span class="token function">SCHEDULER_UNLOCK</span><span class="token punctuation">(</span>intSave<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br></div></div><p><strong>解读</strong></p> <ul><li><p>在信号处理函数完成之后，内核会触发一个<code>__NR_sigreturn</code>的系统调用，又陷入内核态，回到了<code>OsArmA32SyscallHandle</code>。</p></li> <li><p>恢复的过程很简单，把之前保存的信号上下文恢复到内核栈sp开始位置，数据在栈中的保存顺序可查看 用栈方式篇 ，最重要的看这几句。</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code>sp<span class="token punctuation">[</span>REG_PC<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>PC<span class="token punctuation">;</span><span class="token comment">//指令寄存器</span>
sp<span class="token punctuation">[</span>REG_SP<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>USP<span class="token punctuation">;</span><span class="token comment">//用户栈堆栈指针， USP指的是 用户态的堆栈，即将回到用户栈继续运行</span>
sp<span class="token punctuation">[</span>REG_LR<span class="token punctuation">]</span> <span class="token operator">=</span> sigcb<span class="token operator">-&gt;</span>context<span class="token punctuation">.</span>ULR<span class="token punctuation">;</span><span class="token comment">//返回用户栈代码执行位置</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>注意这里还不是真正的切换上下文，只是改变内核栈中现有的数据。这些数据将还原给寄存器。<code>USP</code>和<code>ULR</code>指向的是用户栈的位置。一旦<code>PC</code>，<code>USP</code>，<code>ULR</code>从栈中弹出赋给寄存器。才真正完成了内核栈到用户栈的切换。回到了user.source()继续运行。</p></li> <li><p>真正的切换汇编代码如下，都已添加注释，在保存和恢复上下文中夹着<code>OsArmA32SyscallHandle</code></p> <div class="language- line-numbers-mode"><pre class="language-text"><code>@ Description: Software interrupt exception handler
_osExceptSwiHdl: @软中断异常处理，注意此时已在内核栈运行
@保存任务上下文(TaskContext) 开始... 一定要对照TaskContext来理解
SUB     SP， SP， #(4 * 16)	@先申请16个栈空间单元用于处理本次软中断
STMIA   SP， {R0-R12}		@Taskcontext.R[GEN_REGS_NUM] STMIA从左到右执行，先放R0 。。 R12
MRS     R3， SPSR			@读取本模式下的SPSR值
MOV     R4， LR				@保存回跳寄存器LR

AND     R1， R3， #CPSR_MASK_MODE                          @ Interrupted mode 获取中断模式
CMP     R1， #CPSR_USER_MODE                              @ User mode	是否为用户模式
BNE     OsKernelSVCHandler                               @ Branch if not user mode 非用户模式下跳转
@ 当为用户模式时，获取SP和LR寄出去值
@ we enter from user mode， we need get the values of  USER mode r13(sp) and r14(lr)。
@ stmia with ^ will return the user mode registers (provided that r15 is not in the register list)。
MOV     R0， SP											 @获取SP值，R0将作为OsArmA32SyscallHandle的参数
STMFD   SP!， {R3}                                        @ Save the CPSR 入栈保存CPSR值 =&gt; Taskcontext.regPSR
ADD     R3， SP， #(4 * 17)                                @ Offset to pc/cpsr storage 跳到PC/CPSR存储位置
STMFD   R3!， {R4}                                        @ Save the CPSR and r15(pc) 保存LR寄存器 =&gt; Taskcontext.PC
STMFD   R3， {R13， R14}^                                  @ Save user mode r13(sp) and r14(lr) 从右向左 保存 =&gt; Taskcontext.LR和SP
SUB     SP， SP， #4										 @ =&gt; Taskcontext.resved
PUSH_FPU_REGS R1	@保存中断模式(用户模式)											
@保存任务上下文(TaskContext) 结束
MOV     FP， #0                                           @ Init frame pointer
CPSIE   I	@开中断，表明在系统调用期间可响应中断
BLX     OsArmA32SyscallHandle	/*交给C语言处理系统调用，参数为R0，指向TaskContext的开始位置*/
CPSID   I	@执行后续指令前必须先关中断
@恢复任务上下文(TaskContext) 开始
POP_FPU_REGS R1											 @弹出FPU值给R1
ADD     SP， SP，#4										 @ 定位到保存旧SPSR值的位置
LDMFD   SP!， {R3}                                        @ Fetch the return SPSR 弹出旧SPSR值
MSR     SPSR_cxsf， R3                                    @ Set the return mode SPSR 恢复该模式下的SPSR值

@ we are leaving to user mode， we need to restore the values of USER mode r13(sp) and r14(lr)。
@ ldmia with ^ will return the user mode registers (provided that r15 is not in the register list)

LDMFD   SP!， {R0-R12}									 @恢复R0-R12寄存器
LDMFD   SP， {R13， R14}^                                  @ Restore user mode R13/R14 恢复用户模式的R13/R14寄存器
ADD     SP， SP， #(2 * 4)								 @定位到保存旧PC值的位置
LDMFD   SP!， {PC}^                                       @ Return to user 切回用户模式运行
@恢复任务上下文(TaskContext) 结束
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br></div></div></li></ul> <h3 id="百文说内核-抓住主脉络">百文说内核 | 抓住主脉络</h3> <ul><li>百文相当于摸出内核的肌肉和器官系统，让人开始丰满有立体感，因是直接从注释源码起步，在加注释过程中，每每有心得处就整理,慢慢形成了以下文章。内容立足源码，常以生活场景打比方尽可能多的将内核知识点置入某种场景，具有画面感，容易理解记忆。说别人能听得懂的话很重要! 百篇博客绝不是百度教条式的在说一堆诘屈聱牙的概念，那没什么意思。更希望让内核变得栩栩如生，倍感亲切。</li> <li>与代码需不断<code>debug</code>一样，文章内容会存在不少错漏之处，请多包涵，但会反复修正，持续更新，<code>v**.xx</code> 代表文章序号和修改的次数，精雕细琢，言简意赅，力求打造精品内容。</li> <li>百文在 &lt; 鸿蒙研究站 | 开源中国 | 博客园 | 51cto | csdn | 知乎 | 掘金 &gt; 站点发布，百篇博客系列目录如下。</li> <li><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/common/cate.png" alt=""></li></ul> <p>按功能模块:</p> <table><thead><tr><th style="text-align:center;">基础知识</th> <th style="text-align:center;">进程管理</th> <th style="text-align:center;">任务管理</th> <th style="text-align:center;">内存管理</th></tr></thead> <tbody><tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/01.html" target="_blank" rel="noopener noreferrer">双向链表</a><br><a href="http://weharmonyos.com/blog/02.html" target="_blank" rel="noopener noreferrer">内核概念</a><br><a href="http://weharmonyos.com/blog/03.html" target="_blank" rel="noopener noreferrer">源码结构</a><br><a href="http://weharmonyos.com/blog/04.html" target="_blank" rel="noopener noreferrer">地址空间</a><br><a href="http://weharmonyos.com/blog/05.html" target="_blank" rel="noopener noreferrer">计时单位</a><br><a href="http://weharmonyos.com/blog/06.html" target="_blank" rel="noopener noreferrer">优雅的宏</a><br><a href="http://weharmonyos.com/blog/07.html" target="_blank" rel="noopener noreferrer">钩子框架</a><br><a href="http://weharmonyos.com/blog/08.html" target="_blank" rel="noopener noreferrer">位图管理</a><br><a href="http://weharmonyos.com/blog/09.html" target="_blank" rel="noopener noreferrer">POSIX</a><br><a href="http://weharmonyos.com/blog/10.html" target="_blank" rel="noopener noreferrer">main函数</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/11.html" target="_blank" rel="noopener noreferrer">调度故事</a><br><a href="http://weharmonyos.com/blog/12.html" target="_blank" rel="noopener noreferrer">进程控制块</a><br><a href="http://weharmonyos.com/blog/13.html" target="_blank" rel="noopener noreferrer">进程空间</a><br><a href="http://weharmonyos.com/blog/14.html" target="_blank" rel="noopener noreferrer">线性区</a><br><a href="http://weharmonyos.com/blog/15.html" target="_blank" rel="noopener noreferrer">红黑树</a><br><a href="http://weharmonyos.com/blog/16.html" target="_blank" rel="noopener noreferrer">进程管理</a><br><a href="http://weharmonyos.com/blog/17.html" target="_blank" rel="noopener noreferrer">Fork进程</a><br><a href="http://weharmonyos.com/blog/18.html" target="_blank" rel="noopener noreferrer">进程回收</a><br><a href="http://weharmonyos.com/blog/19.html" target="_blank" rel="noopener noreferrer">Shell编辑</a><br><a href="http://weharmonyos.com/blog/20.html" target="_blank" rel="noopener noreferrer">Shell解析</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/21.html" target="_blank" rel="noopener noreferrer">任务控制块</a><br><a href="http://weharmonyos.com/blog/22.html" target="_blank" rel="noopener noreferrer">并发并行</a><br><a href="http://weharmonyos.com/blog/23.html" target="_blank" rel="noopener noreferrer">就绪队列</a><br><a href="http://weharmonyos.com/blog/24.html" target="_blank" rel="noopener noreferrer">调度机制</a><br><a href="http://weharmonyos.com/blog/25.html" target="_blank" rel="noopener noreferrer">任务管理</a><br><a href="http://weharmonyos.com/blog/26.html" target="_blank" rel="noopener noreferrer">用栈方式</a><br><a href="http://weharmonyos.com/blog/27.html" target="_blank" rel="noopener noreferrer">软件定时器</a><br><a href="http://weharmonyos.com/blog/28.html" target="_blank" rel="noopener noreferrer">控制台</a><br><a href="http://weharmonyos.com/blog/29.html" target="_blank" rel="noopener noreferrer">远程登录</a><br><a href="http://weharmonyos.com/blog/30.html" target="_blank" rel="noopener noreferrer">协议栈</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/31.html" target="_blank" rel="noopener noreferrer">内存规则</a><br><a href="http://weharmonyos.com/blog/32.html" target="_blank" rel="noopener noreferrer">物理内存</a><br><a href="http://weharmonyos.com/blog/33.html" target="_blank" rel="noopener noreferrer">内存概念</a><br><a href="http://weharmonyos.com/blog/34.html" target="_blank" rel="noopener noreferrer">虚实映射</a><br><a href="http://weharmonyos.com/blog/35.html" target="_blank" rel="noopener noreferrer">页表管理</a><br><a href="http://weharmonyos.com/blog/36.html" target="_blank" rel="noopener noreferrer">静态分配</a><br><a href="http://weharmonyos.com/blog/37.html" target="_blank" rel="noopener noreferrer">TLFS算法</a><br><a href="http://weharmonyos.com/blog/38.html" target="_blank" rel="noopener noreferrer">内存池管理</a><br><a href="http://weharmonyos.com/blog/39.html" target="_blank" rel="noopener noreferrer">原子操作</a><br><a href="http://weharmonyos.com/blog/40.html" target="_blank" rel="noopener noreferrer">圆整对齐</a><br></td></tr> <tr><td style="text-align:center;">通讯机制</td> <td style="text-align:center;">文件系统</td> <td style="text-align:center;">硬件架构</td> <td style="text-align:center;">内核汇编</td></tr> <tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/41.html" target="_blank" rel="noopener noreferrer">通讯总览</a><br><a href="http://weharmonyos.com/blog/42.html" target="_blank" rel="noopener noreferrer">自旋锁</a><br><a href="http://weharmonyos.com/blog/43.html" target="_blank" rel="noopener noreferrer">互斥锁</a><br><a href="http://weharmonyos.com/blog/44.html" target="_blank" rel="noopener noreferrer">快锁使用</a><br><a href="http://weharmonyos.com/blog/45.html" target="_blank" rel="noopener noreferrer">快锁实现</a><br><a href="http://weharmonyos.com/blog/46.html" target="_blank" rel="noopener noreferrer">读写锁</a><br><a href="http://weharmonyos.com/blog/47.html" target="_blank" rel="noopener noreferrer">信号量</a><br><a href="http://weharmonyos.com/blog/48.html" target="_blank" rel="noopener noreferrer">事件机制</a><br><a href="http://weharmonyos.com/blog/49.html" target="_blank" rel="noopener noreferrer">信号生产</a><br><a href="http://weharmonyos.com/blog/50.html" target="_blank" rel="noopener noreferrer">信号消费</a><br><a href="http://weharmonyos.com/blog/51.html" target="_blank" rel="noopener noreferrer">消息队列</a><br><a href="http://weharmonyos.com/blog/52.html" target="_blank" rel="noopener noreferrer">消息封装</a><br><a href="http://weharmonyos.com/blog/53.html" target="_blank" rel="noopener noreferrer">消息映射</a><br><a href="http://weharmonyos.com/blog/54.html" target="_blank" rel="noopener noreferrer">共享内存</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/55.html" target="_blank" rel="noopener noreferrer">文件概念</a><br><a href="http://weharmonyos.com/blog/56.html" target="_blank" rel="noopener noreferrer">文件故事</a><br><a href="http://weharmonyos.com/blog/57.html" target="_blank" rel="noopener noreferrer">索引节点</a><br><a href="http://weharmonyos.com/blog/58.html" target="_blank" rel="noopener noreferrer">VFS</a><br><a href="http://weharmonyos.com/blog/59.html" target="_blank" rel="noopener noreferrer">文件句柄</a><br><a href="http://weharmonyos.com/blog/60.html" target="_blank" rel="noopener noreferrer">根文件系统</a><br><a href="http://weharmonyos.com/blog/61.html" target="_blank" rel="noopener noreferrer">挂载机制</a><br><a href="http://weharmonyos.com/blog/62.html" target="_blank" rel="noopener noreferrer">管道文件</a><br><a href="http://weharmonyos.com/blog/63.html" target="_blank" rel="noopener noreferrer">文件映射</a><br><a href="http://weharmonyos.com/blog/64.html" target="_blank" rel="noopener noreferrer">写时拷贝</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/65.html" target="_blank" rel="noopener noreferrer">芯片模式</a><br><a href="http://weharmonyos.com/blog/66.html" target="_blank" rel="noopener noreferrer">ARM架构</a><br><a href="http://weharmonyos.com/blog/67.html" target="_blank" rel="noopener noreferrer">指令集</a><br><a href="http://weharmonyos.com/blog/68.html" target="_blank" rel="noopener noreferrer">协处理器</a><br><a href="http://weharmonyos.com/blog/69.html" target="_blank" rel="noopener noreferrer">工作模式</a><br><a href="http://weharmonyos.com/blog/70.html" target="_blank" rel="noopener noreferrer">寄存器</a><br><a href="http://weharmonyos.com/blog/71.html" target="_blank" rel="noopener noreferrer">多核管理</a><br><a href="http://weharmonyos.com/blog/72.html" target="_blank" rel="noopener noreferrer">中断概念</a><br><a href="http://weharmonyos.com/blog/73.html" target="_blank" rel="noopener noreferrer">中断管理</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/74.html" target="_blank" rel="noopener noreferrer">编码方式</a><br><a href="http://weharmonyos.com/blog/75.html" target="_blank" rel="noopener noreferrer">汇编基础</a><br><a href="http://weharmonyos.com/blog/76.html" target="_blank" rel="noopener noreferrer">汇编传参</a><br><a href="http://weharmonyos.com/blog/77.html" target="_blank" rel="noopener noreferrer">链接脚本</a><br><a href="http://weharmonyos.com/blog/78.html" target="_blank" rel="noopener noreferrer">内核启动</a><br><a href="http://weharmonyos.com/blog/79.html" target="_blank" rel="noopener noreferrer">进程切换</a><br><a href="http://weharmonyos.com/blog/80.html" target="_blank" rel="noopener noreferrer">任务切换</a><br><a href="http://weharmonyos.com/blog/81.html" target="_blank" rel="noopener noreferrer">中断切换</a><br><a href="http://weharmonyos.com/blog/82.html" target="_blank" rel="noopener noreferrer">异常接管</a><br><a href="http://weharmonyos.com/blog/83.html" target="_blank" rel="noopener noreferrer">缺页中断</a><br></td></tr> <tr><td style="text-align:center;">编译运行</td> <td style="text-align:center;">调测工具</td> <td style="text-align:center;"></td> <td style="text-align:center;"></td></tr> <tr><td style="text-align:center;"><a href="http://weharmonyos.com/blog/84.html" target="_blank" rel="noopener noreferrer">编译过程</a><br><a href="http://weharmonyos.com/blog/85.html" target="_blank" rel="noopener noreferrer">编译构建</a><br><a href="http://weharmonyos.com/blog/86.html" target="_blank" rel="noopener noreferrer">GN语法</a><br><a href="http://weharmonyos.com/blog/87.html" target="_blank" rel="noopener noreferrer">忍者无敌</a><br><a href="http://weharmonyos.com/blog/88.html" target="_blank" rel="noopener noreferrer">ELF格式</a><br><a href="http://weharmonyos.com/blog/89.html" target="_blank" rel="noopener noreferrer">ELF解析</a><br><a href="http://weharmonyos.com/blog/90.html" target="_blank" rel="noopener noreferrer">静态链接</a><br><a href="http://weharmonyos.com/blog/91.html" target="_blank" rel="noopener noreferrer">重定位</a><br><a href="http://weharmonyos.com/blog/92.html" target="_blank" rel="noopener noreferrer">动态链接</a><br><a href="http://weharmonyos.com/blog/93.html" target="_blank" rel="noopener noreferrer">进程映像</a><br><a href="http://weharmonyos.com/blog/94.html" target="_blank" rel="noopener noreferrer">应用启动</a><br><a href="http://weharmonyos.com/blog/95.html" target="_blank" rel="noopener noreferrer">系统调用</a><br><a href="http://weharmonyos.com/blog/96.html" target="_blank" rel="noopener noreferrer">VDSO</a><br></td> <td style="text-align:center;"><a href="http://weharmonyos.com/blog/97.html" target="_blank" rel="noopener noreferrer">模块监控</a><br><a href="http://weharmonyos.com/blog/98.html" target="_blank" rel="noopener noreferrer">日志跟踪</a><br><a href="http://weharmonyos.com/blog/99.html" target="_blank" rel="noopener noreferrer">系统安全</a><br><a href="http://weharmonyos.com/blog/100.html" target="_blank" rel="noopener noreferrer">测试用例</a><br></td> <td style="text-align:center;"></td> <td style="text-align:center;"></td></tr></tbody></table> <h3 id="百万注源码-处处扣细节">百万注源码 | 处处扣细节</h3> <ul><li><p>百万汉字注解内核目的是要看清楚其毛细血管，细胞结构，等于在拿放大镜看内核。内核并不神秘，带着问题去源码中找答案是很容易上瘾的，你会发现很多文章对一些问题的解读是错误的，或者说不深刻难以自圆其说，你会慢慢形成自己新的解读，而新的解读又会碰到新的问题，如此层层递进，滚滚向前，拿着放大镜根本不愿意放手。</p></li> <li><p><a href="https://gitee.com/weharmony/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">&lt; gitee</a> | <a href="https://github.com/kuangyufei/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">github</a> | <a href="https://weharmony.coding.net/public/harmony/kernel_liteos_a_note/git/files" target="_blank" rel="noopener noreferrer">coding</a> | <a href="https://gitcode.net/kuangyufei/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer">gitcode &gt;</a> 四大码仓推送 | 同步官方源码。</p> <p><a href="https://gitee.com/weharmony/kernel_liteos_a_note" target="_blank" rel="noopener noreferrer"><img src="https://gitee.com/weharmony/kernel_liteos_a_note/widgets/widget_card.svg?colors=393222,ebdfc1,fffae5,d8ca9f,393222,a28b40" alt=""></a></p></li></ul> <h3 id="关注不迷路-代码即人生">关注不迷路 | 代码即人生</h3> <p><img src="https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/common/so1so.png" alt=""></p> <ul><li>互联网从业十五年，计算机硕士，技术副总裁</li> <li>关注我，持续更新四十年，即聊技术也聊人生</li> <li>交有趣靠谱的人；做难而正确的事</li> <li>不做作，不炒作，只唯真</li> <li>不唯上，不唯书，只唯实</li></ul> <p><a href="http://weharmonyos.com/donate.html" target="_blank" rel="noopener noreferrer"> &gt;&gt; 捐助名单</a></p> <p>据说喜欢 <strong>点赞 + 分享</strong> 的,后来都成了大神。😃</p></div> <!----> <div class="content__content-bottom"></div> <footer class="page-meta"><!----> <!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev"><a href="/blog/49.html" class="prev"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon prev-icon"><path d="M906.783 588.79c-.02 8.499-6.882 15.36-15.38 15.37l-443.7-.01 75.704 191.682c2.52 6.42.482 13.763-5.038 17.91-5.52 4.168-13.138 4.147-18.616-.092L123.228 524.175a15.362 15.362 0 0 1-6-12.165c0-4.782 2.222-9.277 6-12.185L499.753 210.35a15.388 15.388 0 0 1 9.38-3.195c3.236 0 6.502 1.034 9.236 3.103 5.52 4.147 7.578 11.49 5.038 17.91L447.683 419.84l443.72-.01c8.498.01 15.36 6.881 15.36 15.36l.02 153.6z" fill="currentColor"></path></svg>
        信号生产
      </a></span> <span class="next"><a href="/blog/51.html">
        消息队列
        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon next-icon"><path d="M906.772 512c0 4.772-2.211 9.267-5.99 12.175L524.257 813.66a15.37 15.37 0 0 1-18.616.092 15.368 15.368 0 0 1-5.038-17.91l75.714-191.672h-443.73c-8.488 0-15.36-6.881-15.36-15.36v-153.6c0-8.489 6.872-15.36 15.36-15.36h443.73l-75.714-191.682a15.358 15.358 0 0 1 5.048-17.91c5.51-4.158 13.128-4.137 18.606.092l376.525 289.485a15.323 15.323 0 0 1 5.99 12.165z" fill="currentColor"></path></svg></a></span></p></div> <!----> <!----> <div class="content__page-bottom"></div></main> <!----></div><div class="global-ui"><!----><!----><div id="pwa-install"><!----> <div id="install-modal-wrapper" style="display:none;"><div class="background"></div> <div class="install-modal"><div class="header"><button aria-label="Close" class="close-button"><svg width="23" height="22" xmlns="http://www.w3.org/2000/svg" class="icon close-icon"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.12.358a1.224 1.224 0 011.729 0l8.92 8.914L20.686.358a1.224 1.224 0 011.73 1.728L13.497 11l8.92 8.913a1.222 1.222 0 11-1.73 1.729l-8.919-8.913-8.92 8.913a1.224 1.224 0 01-1.729-1.729L10.04 11l-8.92-8.914a1.222 1.222 0 010-1.728z" fill="currentColor"></path></svg></button> <div class="logo"><!----> <div class="title"><h1></h1> <p class="desc">This app can be installed on your PC or mobile device.  This will allow this web app to look and behave like any other installed app.  You will find it in your app lists and be able to pin it to your home screen, start menus or task bars.  This installed web app will also be able to safely interact with other apps and your operating system. </p></div></div></div> <div class="content"><div class="highlight"><!----> <!----></div> <div class="description"><h3>Description</h3> <p></p></div></div> <div class="button-wrapper"><button class="install-button">
        Install <span></span></button> <button class="cancel-button">
        Cancel
      </button></div></div></div></div><div tabindex="-1" role="dialog" aria-hidden="true" class="pswp"><div class="pswp__bg"></div> <div class="pswp__scroll-wrap"><div class="pswp__container"><div class="pswp__item"></div> <div class="pswp__item"></div> <div class="pswp__item"></div></div> <div class="pswp__ui pswp__ui--hidden"><div class="pswp__top-bar"><div class="pswp__counter"></div> <button title="Close" aria-label="Close" class="pswp__button pswp__button--close"></button> <button title="Share" aria-label="Share" class="pswp__button pswp__button--share"></button> <button title="Switch to full screen" aria-label="Switch to full screen" class="pswp__button pswp__button--fs"></button> <button title="Zoom in/out" aria-label="Zoom in/out" class="pswp__button pswp__button--zoom"></button> <div class="pswp__preloader"><div class="pswp__preloader__icn"><div class="pswp__preloader__cut"><div class="pswp__preloader__donut"></div></div></div></div></div> <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap"><div class="pswp__share-tooltip"></div></div> <button title="Prev (Arrow Left)" aria-label="Prev (Arrow Left)" class="pswp__button pswp__button--arrow--left"></button> <button title="Next (Arrow Right)" aria-label="Next (Arrow Right)" class="pswp__button pswp__button--arrow--right"></button> <div class="pswp__caption"><div class="pswp__caption__center"></div></div></div></div></div></div></div>
    <script src="/assets/js/app.9a8b95d8.js" defer></script><script src="/assets/js/vendors~layout-Layout.c1e797d4.js" defer></script><script src="/assets/js/vendors~layout-Blog~layout-Layout~layout-NotFound.f75cf258.js" defer></script><script src="/assets/js/page--48302d68.8d6493cf.js" defer></script>
  </body>
</html>
